package com.tianqi.modules.pms.service.impl;

import com.nlf.calendar.Lunar;
import com.nlf.calendar.Solar;
import com.tianqi.common.constant.LittleLiuRenConstant;
import com.tianqi.common.constant.ZiWeiDouShuConstant;
import com.tianqi.common.enums.GenderTypeEnum;
import com.tianqi.common.utils.LunarDateUtil;
import com.tianqi.modules.pms.dto.request.ArrangeDiskReqDTO;
import com.tianqi.modules.pms.dto.response.ziwei.ZiWeiDaXian;
import com.tianqi.modules.pms.dto.response.ziwei.ZiWeiDouShuResp;
import com.tianqi.modules.pms.dto.response.ziwei.ZiWeiGong;
import com.tianqi.modules.pms.service.ZiWeiDouShuService;
import com.tianqi.modules.tqs.constant.RelationMapConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * 获取紫微斗数排盘
 *
 * @author zhangzedi
 * @date 2023/8/24 00:10
 **/
@Service
@Slf4j
public class ZiWeiDouShuServiceImpl implements ZiWeiDouShuService {

	@Autowired
	private LunarDateUtil lunarDateUtil;

	/**
	 * 获取紫微斗数排盘数据
	 *
	 * @param reqDTO
	 * @return
	 */
	@Override
	public ZiWeiDouShuResp getZiWeiDouShu(ArrangeDiskReqDTO reqDTO) {
		log.info("开始计算紫微斗数");
		long startMills = System.currentTimeMillis();
		ZiWeiDouShuResp ziWeiDouShuResp = new ZiWeiDouShuResp();
		ziWeiDouShuResp.setName(reqDTO.getName());
		// 根据入参的生辰获取农历日期
		Lunar birthLunar = lunarDateUtil.formatEightChar(reqDTO.getBirthDay());
		Solar birthSolar = birthLunar.getSolar();
		String solarStr =
				birthSolar.getYear() + "年" + birthLunar.getMonth() + "月" + birthSolar.getDay() + "日" + birthSolar.getHour() + "时";
		ziWeiDouShuResp.setSolarStr(solarStr);
		String lunarStr =
				birthLunar.getYearInGanZhi() + "年" + birthLunar.getMonth() + "月" + birthLunar.getDay() + "日 " + birthLunar.getTimeZhi() + "时";
		ziWeiDouShuResp.setLunarStr(lunarStr);
		// 判断阳年阴年
		boolean yangFlag =
				LittleLiuRenConstant.YINGYANG_TIANGAN.get(LittleLiuRenConstant.YANG).contains(birthLunar.getMonthGan());
		ziWeiDouShuResp.setGender(yangFlag ?
				LittleLiuRenConstant.YANG + GenderTypeEnum.getGenderByCode(reqDTO.getGenderType()).getInfo() :
				LittleLiuRenConstant.YIN + GenderTypeEnum.getGenderByCode(reqDTO.getGenderType()).getInfo());
		// 获取十二宫的信息
		List<ZiWeiGong> ziWeiGongList = getShiErGong(birthLunar, reqDTO.getGenderType());
		ziWeiDouShuResp.setZiWeiGongList(ziWeiGongList);
		// 设置五行局

		long endMills = System.currentTimeMillis();
		log.info("紫微斗数耗时：{}毫秒", endMills - startMills);
		return ziWeiDouShuResp;
	}


	/**
	 * 设置十二宫
	 *
	 * @param birthLunar
	 * @return
	 */
	private List<ZiWeiGong> getShiErGong(Lunar birthLunar, Integer gender) {
		List<ZiWeiGong> ziWeiGongList = new ArrayList<>(12);
		// 判断阳年阴年
		boolean yangFlag =
				LittleLiuRenConstant.YINGYANG_TIANGAN.get(LittleLiuRenConstant.YANG).contains(birthLunar.getMonthGan());
		List<String> monthDiZhis = ZiWeiDouShuConstant.YEARGAN_MONGZHI_MAP.get(birthLunar.getYearGan());
		// 获取命宫的位置
		int mingGongIndex = getMingGongIndex(birthLunar);
		// 获取身宫位置
		int shenGongIndex = getShenGongIndex(birthLunar);
		// 是否顺时针
		boolean clockwise;
		// 判断顺数逆数
		if (yangFlag) {
			clockwise = gender.equals(GenderTypeEnum.MALE.getCode());
		} else {
			clockwise = !gender.equals(GenderTypeEnum.MALE.getCode());
		}
		//	先在总外边安放一个大循环，从寅开始循环
		for (int i = 1; i < monthDiZhis.size(); i++) {
			ZiWeiGong ziWeiGong = new ZiWeiGong();
			ziWeiGong.setIndex(i);
			//先设置干支，从寅开始
			ziWeiGong.setZhi(monthDiZhis.get(i).substring(1));
			ziWeiGong.setGan(String.valueOf(monthDiZhis.get(i).charAt(0)));
			if (clockwise) {
				// 顺数时
				if (i + mingGongIndex <= 13) {
					ziWeiGong.setTwelveGong(ZiWeiDouShuConstant.SHIER_GONG[i + mingGongIndex - 1]);
				} else {
					ziWeiGong.setTwelveGong(ZiWeiDouShuConstant.SHIER_GONG[i + mingGongIndex - 13]);
				}
			} else {
				// 逆数时
				if (i <= mingGongIndex) {
					ziWeiGong.setTwelveGong(ZiWeiDouShuConstant.SHIER_GONG[mingGongIndex - i + 1]);
				} else {
					ziWeiGong.setTwelveGong(ZiWeiDouShuConstant.SHIER_GONG[13 + mingGongIndex - i]);
				}
			}

			// 设置身宫
			if (shenGongIndex == i) {
				ziWeiGong.setShenGong(true);
			}
			ziWeiGongList.add(ziWeiGong);
		}
		ZiWeiGong mingGong = ziWeiGongList.get(mingGongIndex - 1);
		List<ZiWeiDaXian> ziWeiDaXianList = new ArrayList<>(12);
		// 根据命宫所在宫的干支查询命宫的纳音
		String mingGongNaYin = RelationMapConstant.JIAZI_NAYIN_MAP.get(mingGong.getGan() + mingGong.getZhi());
		Integer yunAge = ZiWeiDouShuConstant.WU_XING_JU.get(mingGongNaYin.substring(2));
		for (int i = 0; i < ziWeiGongList.size(); i++) {
			ZiWeiDaXian ziWeiDaXian = new ZiWeiDaXian();
			ZiWeiGong ziWeiGong = ziWeiGongList.get(i);
			// 判断顺时针逆时针
			if (clockwise) {
				if (i + 1 <= mingGongIndex) {
					ziWeiGong.setDaXianStartAge((i + 13 - mingGongIndex) * 10 + yunAge);
				} else {
					ziWeiGong.setDaXianStartAge((i + 1 - mingGongIndex) * 10 + yunAge);
				}
			} else {
				// 逆时针
				if (i + 1 <= mingGongIndex) {
					ziWeiGong.setDaXianStartAge((mingGongIndex - i - 1) * 10 + yunAge);
				} else {
					ziWeiGong.setDaXianStartAge((11 + mingGongIndex - i) * 10 + yunAge);
				}
			}
			ziWeiGong.setDaXianEndAge(ziWeiGong.getDaXianStartAge() + 9);
			ziWeiDaXian.setDaXianStartAge(ziWeiGong.getDaXianStartAge());
			ziWeiDaXian.setDaXianEndAge(ziWeiGong.getDaXianEndAge());
			ziWeiDaXian.setGanZhi(ziWeiGong.getGan() + ziWeiGong.getZhi());
		}
		return ziWeiGongList;
	}

	/**
	 * 获取命宫的位置
	 *
	 * @param birthLunar
	 * @return
	 */
	private int getMingGongIndex(Lunar birthLunar) {
		// 根据生辰月份和生辰时辰定命宫，身宫
		// 命宫先从从寅宫起正月，数到生月，又自人生月起子时逆至本生时安命，顺至本生时安身
		// 判断时辰和生月那个大,注意此时的时辰地支是从0开始的，即子时是0
		int mingGongIndex;
		if (birthLunar.getMonth() >= (birthLunar.getTimeZhiIndex() + 1)) {
			mingGongIndex = birthLunar.getMonth() - birthLunar.getTimeZhiIndex();
		} else {
			mingGongIndex = 12 - birthLunar.getTimeZhiIndex() + birthLunar.getMonth();
		}
		return mingGongIndex;
	}

	/**
	 * 获取身宫的位置
	 *
	 * @param birthLunar
	 * @return
	 */
	private int getShenGongIndex(Lunar birthLunar) {
		int shenGongIndex;
		if ((birthLunar.getMonth() + birthLunar.getTimeZhiIndex()) <= 12) {
			shenGongIndex = birthLunar.getMonth() + birthLunar.getTimeZhiIndex();
		} else {
			shenGongIndex = birthLunar.getMonth() + birthLunar.getTimeZhiIndex() - 12;
		}
		return shenGongIndex;
	}

	/**
	 * 设置五行局等相关参数
	 *
	 * @param birthLunar
	 * @param ziWeiDouShuResp
	 */
	private void setWuXingJu(Lunar birthLunar, ZiWeiDouShuResp ziWeiDouShuResp) {
		// 获取命宫的位置
		int mingGongIndex = getMingGongIndex(birthLunar);
		ZiWeiGong mingGong = ziWeiDouShuResp.getZiWeiGongList().get(mingGongIndex - 1);
		// 根据命宫所在宫的干支查询命宫的纳音
		String mingGongNaYin = RelationMapConstant.JIAZI_NAYIN_MAP.get(mingGong.getGan() + mingGong.getZhi());
		Integer yunAge = ZiWeiDouShuConstant.WU_XING_JU.get(mingGongNaYin.substring(2));
	}
}
